From 6e96111d9f5e9298ff0b716f063b084a94a880e6 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 24 Jan 2014 15:40:37 -0500 Subject: [PATCH] GtkHeaderBar: try harder to find the best window icon GtkWindow has 4 (!) APIs for setting window icons, and we have to try them all in the right order to find the right icon. This commit makes it so, and keeps the icon list manipulation inside gtkwindow.c by adding a private API for getting a single icon at the right size. https://bugzilla.gnome.org/show_bug.cgi?id=722515 --- gtk/gtkheaderbar.c | 46 ++++------------------------- gtk/gtkwindow.c | 67 ++++++++++++++++++++++++++++++++++++++++++ gtk/gtkwindowprivate.h | 3 ++ 3 files changed, 76 insertions(+), 40 deletions(-) diff --git a/gtk/gtkheaderbar.c b/gtk/gtkheaderbar.c index 3b9923eea2..36c7e70081 100644 --- a/gtk/gtkheaderbar.c +++ b/gtk/gtkheaderbar.c @@ -218,54 +218,20 @@ _gtk_header_bar_update_window_icon (GtkHeaderBar *bar, GtkWindow *window) { GtkHeaderBarPrivate *priv = gtk_header_bar_get_instance_private (bar); - gint size; - GList *list; - const gchar *name; - GdkPixbuf *best = NULL; + GdkPixbuf *pixbuf; if (priv->titlebar_icon == NULL) return FALSE; if (GTK_IS_BUTTON (gtk_widget_get_parent (priv->titlebar_icon))) - size = 16; + pixbuf = gtk_window_get_icon_for_size (window, 16); else - size = 20; + pixbuf = gtk_window_get_icon_for_size (window, 20); - list = gtk_window_get_icon_list (window); - - if (list != NULL) - { - GdkPixbuf *pixbuf; - GList *l; - - best = NULL; - for (l = list; l; l = l->next) - { - pixbuf = list->data; - if (gdk_pixbuf_get_width (pixbuf) <= size) - { - best = g_object_ref (pixbuf); - break; - } - } - - if (best == NULL) - best = gdk_pixbuf_scale_simple (GDK_PIXBUF (list->data), size, size, GDK_INTERP_BILINEAR); - - g_list_free (list); - } - else - { - name = gtk_window_get_icon_name (window); - if (name != NULL) - best = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), - name, size, GTK_ICON_LOOKUP_FORCE_SIZE, NULL); - } - - if (best) + if (pixbuf) { - gtk_image_set_from_pixbuf (GTK_IMAGE (priv->titlebar_icon), best); - g_object_unref (best); + gtk_image_set_from_pixbuf (GTK_IMAGE (priv->titlebar_icon), pixbuf); + g_object_unref (pixbuf); gtk_widget_show (priv->titlebar_icon); return TRUE; diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index f42f9f76a9..5e2cc05aee 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -4019,6 +4019,73 @@ gtk_window_realize_icon (GtkWindow *window) } } +static GdkPixbuf * +icon_from_list (GList *list, + gint size) +{ + GdkPixbuf *best; + GdkPixbuf *pixbuf; + GList *l; + + best = NULL; + for (l = list; l; l = l->next) + { + pixbuf = list->data; + if (gdk_pixbuf_get_width (pixbuf) <= size) + { + best = g_object_ref (pixbuf); + break; + } + } + + if (best == NULL) + best = gdk_pixbuf_scale_simple (GDK_PIXBUF (list->data), size, size, GDK_INTERP_BILINEAR); + + return best; +} + +static GdkPixbuf * +icon_from_name (const gchar *name, + gint size) +{ + return gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + name, size, + GTK_ICON_LOOKUP_FORCE_SIZE, NULL); +} + +GdkPixbuf * +gtk_window_get_icon_for_size (GtkWindow *window, + gint size) +{ + GtkWindowPrivate *priv = window->priv; + GtkWindowIconInfo *info; + const gchar *name; + + info = ensure_icon_info (window); + + if (info->icon_list != NULL) + return icon_from_list (info->icon_list, size); + + name = gtk_window_get_icon_name (window); + if (name != NULL) + return icon_from_name (name, size); + + if (priv->transient_parent != NULL) + { + info = ensure_icon_info (priv->transient_parent); + if (info->icon_list) + return icon_from_list (info->icon_list, size); + } + + if (default_icon_list != NULL) + return icon_from_list (default_icon_list, size); + + if (default_icon_name != NULL) + return icon_from_name (default_icon_name, size); + + return NULL; +} + static void gtk_window_unrealize_icon (GtkWindow *window) { diff --git a/gtk/gtkwindowprivate.h b/gtk/gtkwindowprivate.h index 9f9bce6bd0..704026d001 100644 --- a/gtk/gtkwindowprivate.h +++ b/gtk/gtkwindowprivate.h @@ -107,6 +107,9 @@ void _gtk_window_get_popover_position (GtkWindow *window, GtkPositionType *pos, cairo_rectangle_int_t *rect); +GdkPixbuf *gtk_window_get_icon_for_size (GtkWindow *window, + gint size); + G_END_DECLS #endif /* __GTK_WINDOW_PRIVATE_H__ */ -- 2.30.2